package com.pengpeng.sheepfoldmall.product;

import com.baomidou.mybatisplus.annotation.TableId;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * SpringBoot整合MyBatis
 *      1.引入依赖
 *          sheepfold-common 通用模块中导入 MyBatis 依赖
 *      2.配置
 *          （1）配置数据源
 *              ①sheepfold-common 通用模块中引入数据库驱动依赖
 *              ②application.yml中配置mysql数据源相关信息
 *          （2）配置MyBatis
 *              ①启动类增加@MapperScan或在Mapper接口中标注@Mapper注解
 *              ②application.yml中配置MyBatis相关信息
 *
 * 将微服务注册到Nacos服务注册中心
 *      1.引入依赖
 *          sheepfold-common 通用模块中导入 Nacos服务注册与发现依赖
 *      2.配置
 *          application.yml 文件中配置注册中心地址
 *      3.启动类加上 @EnableDiscoveryClient 注解以开启服务注册发现功能
 *      4.细节点：application.yml 文件中要配置服务名 application.name: sheepfold-product 供注册中心发现
 *
 * 调用远程服务
 *      1.引入依赖
 *          sheepfold-common 通用模块中导入 openfeign远程调用依赖
 *      2.编写一个接口，告诉SpringCloud要调用哪个远程服务
 *      3.调用方启动类上加入 @EnableFeignClients 注解开启远程调用
 *
 * nacos作为配置中心统一管理配置（应用上线后，若需修改配置，不可能重启项目重新发布，这时就需要配置中心动态发布）
 *      1.引入依赖
 *             sheepfold-common 通用模块中导入 Nacos 配置中心依赖
 *      2.创建一个bootstrap.properties 配置文件（bootstrap配置文件加载优先级比application配置文件高）
 *          spring.application.name=nacos-config-example
 *          spring.cloud.nacos.config.server-addr=127.0.0.1:8848
 *          配置文件中主要配置应用名和配置中心地址
 *      3.在配置中心添加一个默认的数据集（Data Id），默认名为服务名.properties
 *      4.在 服务名.properties 中添加配置
 *      5.动态获取配置
 *          在应用中使用 @Value 和 @RefreshScope
 *          @RefreshScope：动态获取并刷新配置
 *          @Value("配置项的名字")：获取配置
 *          TODO：如果配置中心和当前服务中的application.properties配置文件中的配置相同，优先使用配置中心的配置
 *
 * 其他核心概念
 *      1.命名空间（配置隔离）
 *          默认: public(保留空间);默认新增的所有配置都在public空间。
 *          （1）开发，测试，生产:利用命名空间来做环境隔离。在 bootstrap.properties 配置需要使用哪个命名空间下的配置
 *              例：spring.cloud.nacos.config.namespace=9de62e44-cd2a-4a82-bf5c-95878bd5e871
 *          （2）每一个微服务之间互相隔离配置，每一个微服务都创建自己的命名空间，只加载自己命名空间下的所有配置
 *      2.配置集：所有配置的集合
 *      3.配置集id：类似文件名
 *          Data Id：默认名为服务名.properties
 *      4.配置分组：默认所有的配置集都属于 DEFAULT_GROUP
 *          例：spring.cloud.nacos.config.group=dev
 *      TODO:每个微服务创建自己的命名空间，使用配置分组区分环境：dev、prod、test
 *
 * 加载多配置文件
 *      1.微服务中任何配置文件、任何配置信息都可以放在配置中心中
 *          随着服务中的内容增加，可以将一个配置文件根据功能拆分为多个配置文件放到配置中心中
 *      2.只需要在bootstrap.properties中说明要加载的配置文件即可
 *          例：spring.cloud.nacos.config.server-addr=127.0.0.1:8848
 *             spring.cloud.nacos.config.namespace=31098de9-fa28-41c9-b0bd-c754ce319ed4
 *             spring.cloud.nacos.config.ext-config[0].data-id=gulimall-datasource.yml
 *             spring.cloud.nacos.config.ext-config[0].refresh=false
 *             spring.cloud.nacos.config.ext-config[0].group=dev
 *
 * 逻辑删除
 *      1.配置全局的逻辑删除规则（可省略）
 *          mybatis-plus:
                global-config:
                    db-config:
                        logic-delete-value: 1
                        logic-not-delete-value: 0
 *      2.配置逻辑删除的组件Bean（Mybatis3.1.1后的版本无需再配置）
 *      3.给对应的Bean上加入逻辑删除的注解@TableLogic()
 *          因为全局逻辑删除规则默认‘1’为删除，‘0’为不删除
 *          所以如果业务逻辑和全局配置冲突的话，可以在@TableLogic注解中添加属性(value = "1",delval = "0")
 *              value：不删除    delval：删除
 *
 * 对象存储oss
 *      1.引入依赖
 *          sheepfold-common 通用模块中导入 spring-cloud-starter-alicloud-oss 配置中心依赖
 *      2.yml文件配置
 *          spring:
     *          alicloud:
     *              access-key: LTAI5tBgHEGJQWAR9imXimFj
     *              secret-key: wprM7k4gdEzMuxdapFhu5lBjtdjx3F
     *              oss:
     *              endpoint: oss-cn-beijing.aliyuncs.com
 *      3.代码中使用OSSClient进行相关操作
 *
 * JSR303
 *      1.bean中标注 @Blank 等校验注解，并定义自己的message提示
 *      2.在Controller接收参数的地方标注@Valid注解开启校验功能
 *          这样在发生相应错误时会有默认的响应
 *      3.紧跟开启校验的参数后，写上 BindingResult ，就可以获取校验的结果
 *      4.@NotNull、@NotEmpty和@NotBlank三者的区别
 *          （1）@NotNull：不能为null，其他没有要求
 *          （2）@NotEmpty：不能为null且长度不能为0，可用于判断String、Collection、Map、数组
 *          （3）@NotBlank：不能为null且长度不能为0，与@NotEmpty的区别在于，尾部空格被忽略，也就是说，纯空格的String也是不符合规则的，
 *              只能用来判断String类型
 *      5.分组校验（多场景的复杂校验）
 *          （1）@NotBlank(message = "品牌名不得为空",groups = {AddGroup.class, UpdateGroup.class})
 *              给bean属性校验注解添加分组，表示什么情况下生效
 *          （2）@Validated({AddGroup.class})
 *              给接収方法的参数添加@Validated注解，并指定什么分组情况下生效
 *          （3）默认没有添加分组的校验注解，在分组校验情况下不生效，只有在@Validated()时生效
 *      6.自定义校验
 *          （1）编写自定义校验注解
 *          （2）编写自定义校验器
 *              实现ConstraintValidator<ListValue,Integer>接口，第一个参数为要校验的注解，第二个参数为指定要校验什么类型的数据
 *          （3）关联自定义校验器和自定义校验注解
 *              可关联多个自定义校验器，各个校验器的第二个参数也就是校验类型不一样
 *
 *
 * redis
 *      1、引入依赖
 *          pom文件引入 <artifactId>spring-boot-starter-data-redis</artifactId>
 *      2、配置文件配置redis的host等信息
 *      3、使用SpringBoot的RedisTemplate操作redis
 */
@SpringBootApplication
@MapperScan("com.pengpeng.sheepfoldmall.product.dao")
@EnableDiscoveryClient  //开启服务注册发现功能
@EnableFeignClients(basePackages = "com.pengpeng.sheepfoldmall.product.feign")  //开启远程调用功能
public class SheepfoldProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(SheepfoldProductApplication.class, args);
    }

}
